<?php
/**
 * Created by PhpStorm.
 * User: rocky
 * Date: 2020-02-21
 * Time: 12:25
 */

namespace app\common\tools;



use WeChat\Contracts\Tools;

/**
 * REST API服务格式curl请求类
 * Class RestRequest
 * @package buildView
 * @method array get($url,$params=[],$headers=[],$options=[]) GET方法请求
 * @method array post($url,$params=[],$headers=[],$options=[]) POST方法请求
 * @method array put($url,$params=[],$headers=[],$options=[]) PUT方法请求
 * @method array delete($url,$params=[],$headers=[],$options=[]) DELETE方法请求
 */
class RestRequest
{
    /**
     * 静态魔术加载方法
     * @param string $name 静态类名
     * @param array $arguments 参数集合
     * @return mixed
     * @throws \SoapFault
     * @throws \think\Exception
     * @throws \think\exception\PDOException
     */
    public static function __callStatic($name, $arguments)
    {
       $self =self::class;
       array_splice($arguments, 1, 0, $name);
       return call_user_func_array([$self,'http'],$arguments);
    }
    /**
     * 接口请求
     * @param $url 接口地址
     * @param string $method 请求方法 GET | POST
     * @param array $params 参数
     * @param array $headers header请求头
     * @param array $options 请求参数[headers,data,ssl_cer,ssl_key]
     * @return array
     */
    public static function http($url, $method = 'GET',$params = [] , $headers = [],$options = [])
    {
        $method = strtoupper($method);
        $options['headers'] = $headers;
        switch ($method) {
            case 'POST':
                $options['data'] = $params;
                $res = self::doRequest($method, $url, $options);
                if (!empty($res)) {
                    $res = Tools::json2arr($res);
                }
                break;
            case 'GET':
                $options['query'] = $params;
                $res = self::doRequest($method, $url, $options);
                if (!empty($res)) {
                    $res = Tools::json2arr($res);
                }
                break;
            case 'PUT':
                $options['data'] = $params;
                $res = self::doRequest($method, $url, $options);
                if (!empty($res)) {
                    $res = Tools::json2arr($res);
                }
                break;
            case 'DELETE':
                $options['data'] = $params;
                $res = self::doRequest($method, $url, $options);
                if (!empty($res)) {
                    $res = Tools::json2arr($res);
                }
                break;
        }

        return $res;
    }

    /**
     * CURL模拟网络请求
     * @param string $method 请求方法
     * @param string $url 请求方法
     * @param array $options 请求参数[headers,data,ssl_cer,ssl_key]
     * @return boolean|string
     * @throws LocalCacheException
     */
    private static function doRequest($method, $url, $options = [])
    {
        $curl = curl_init();
        // GET参数设置
        if (!empty($options['query'])) {
            $url .= (stripos($url, '?') !== false ? '&' : '?') . http_build_query($options['query']);
        }
        // CURL头信息设置
        if (!empty($options['headers'])) {
            curl_setopt($curl, CURLOPT_HTTPHEADER, $options['headers']);
        }
        // POST数据设置
        if (strtolower($method) === 'post') {
            curl_setopt($curl, CURLOPT_POST, true);
            curl_setopt($curl, CURLOPT_POSTFIELDS, self::_buildHttpData($options['data']));
        }
        if($method === 'PUT' || $method === 'DELETE'){
            curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
            curl_setopt($curl, CURLOPT_POSTFIELDS, self::_buildHttpData($options['data']));
        }
        // 证书文件设置
        if (!empty($options['ssl_cer'])) if (file_exists($options['ssl_cer'])) {
            curl_setopt($curl, CURLOPT_SSLCERTTYPE, 'PEM');
            curl_setopt($curl, CURLOPT_SSLCERT, $options['ssl_cer']);
        } else throw new \HttpInvalidParamException("Certificate files that do not exist. --- [ssl_cer]");
        // 证书文件设置
        if (!empty($options['ssl_key'])) if (file_exists($options['ssl_key'])) {
            curl_setopt($curl, CURLOPT_SSLKEYTYPE, 'PEM');
            curl_setopt($curl, CURLOPT_SSLKEY, $options['ssl_key']);
        } else throw new \HttpInvalidParamException("Certificate files that do not exist. --- [ssl_key]");
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_TIMEOUT, 60);
        curl_setopt($curl, CURLOPT_HEADER, false);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        list($content) = [curl_exec($curl), curl_close($curl)];
        return $content;
    }
    private static function _buildHttpData($data){
        if(is_array($data)){
            return http_build_query($data);
        }else{
            return $data;
        }
    }
}